
Si has llegado hasta aquí, probablemente te preguntes cómo funciona este blog por dentro. La verdad es que mi objetivo principal siempre ha sido no complicarme la vida… y, de paso, hacer todo lo más friki posible. Así que aquí va la explicación completa de cómo escribo, sincronizo, despliego y publico los posts.
1. Escribiendo los posts en Obsidian
Todo empieza en Obsidian, pero ahora con superpoderes. Utilizo Gemini CLI directamente en mi terminal para ayudarme a redactar borradores, revisar la ortografía o reestructurar ideas. Una vez tengo el contenido, uso un template que me ayuda a meter todos los parámetros que mi blog necesita:
external: false title: "Birras, vpn y ponys"
description: "Beer conversation about networks and stuff"
date: 2025-01-04
tags: ["proxy","vpn" ,"networks", "Tor", "deep weeb"]
draft: false
image: "https://cdn.leonardo.ai/users/.../AlbedoBase_XL_show_me_a_network_diagram_based_on_tor_and_proxy_0.jpg"
Sí, soy de los que ponen tags frikis, imágenes raras y descripciones que solo yo entiendo a veces. Pero gracias a esto, cuando escribo un post ya tengo todos los metadatos listos.
2. Automatizando la publicación con Gemini CLI
Aquí es donde la cosa se pone interesante. Antes ejecutaba scripts manualmente, pero ahora he creado un comando personalizado en Gemini CLI llamado /publish. Este comando está definido en un archivo .toml que le dice a la IA exactamente qué pasos seguir:
description = "Automatización completa del blog"
prompt = ""
1. Hay que mover los post mencionados por el usuario de la carpeta draft a la carpeta blog
2. hay que desmarcar la propiedad draft de los mismos.
3. Inicia secuencia de publicación del blog...
!{powershell -File "_System/scripts/publish_blog.ps1"}
"""
Cuando ejecuto /publish, Gemini realiza esta secuencia:
- Organiza: Mueve el archivo markdown desde mi carpeta de borradores (
Drafts) a la carpetaBlogfinal. - Valida: Cambia automáticamente la propiedad
draft: trueafalseen el archivo. - Ejecuta: Lanza un script de PowerShell (
publish_blog.ps1) que orquesta todo el despliegue técnico.
El motor: Script de Python y Git
El script de PowerShell llama a mi fiel script de Python, que es el que hace la magia de transformación de los archivos. Básicamente:
1️⃣ Busca todos los archivos Markdown en tu vault de Obsidian
for root, _, files in os.walk(OBSIDIAN_VAULT_PATH):
for file in files:
if file.endswith(".md"):
# Aquí se procesará cada archivo Markdown
obsidian_md_path = os.path.join(root, file)
os.walk recorre recursivamente todas las carpetas del vault. file.endswith(".md") asegura que solo se procesen archivos Markdown.
2️⃣ Copia las imágenes referenciadas desde la carpeta de archivos pegados (Archives) al repositorio Astro
def copy_images(md_content, dest_folder):
image_paths = re.findall(r'Pasted image.*?\.png', md_content)
updated_md_content = md_content
for image_path in image_paths:
normalized_image_name = image_path.replace(" ", "_")
full_image_path = os.path.join(OBSIDIAN_ARCHIVES_PATH, image_path)
if os.path.exists(full_image_path):
if not os.path.exists(dest_folder):
os.makedirs(dest_folder)
dest_image_path = os.path.join(dest_folder, normalized_image_name)
shutil.copy(full_image_path, dest_image_path)
updated_md_content = updated_md_content.replace(
f"![[{image_path}]]",
f""
)
return updated_md_content
Encuentra las imágenes con nombres como "Pasted image...".
Las copia a la carpeta de destino en el repositorio Astro. Normaliza los nombres reemplazando espacios por "_".
3️⃣ Actualiza los links de las imágenes dentro del Markdown para que funcionen en tu sitio web
updated_md_content = re.sub(
r'!\[\[.*?\]\]\((.*?)\)',
lambda match: f"})",
updated_md_content
)
Esto cambia cualquier referencia de imagen estilo Obsidian a la sintaxis estándar Markdown compatible con tu sitio web.
4️⃣ Copia el archivo Markdown completo a la carpeta de contenido de Astro, respetando la estructura de carpetas original
astro_md_folder = os.path.join(ASTRO_REPO_CONTENT_PATH, relative_path)
astro_md_path = os.path.join(astro_md_folder, file)
if not os.path.exists(astro_md_folder):
os.makedirs(astro_md_folder)
with open(astro_md_path, "w", encoding="utf-8") as f:
f.write(updated_md_content)
Crea las carpetas necesarias en el repositorio Astro. Escribe el Markdown actualizado en la ruta correcta.
5️⃣ Repite el proceso para todos los archivos .md
for root, _, files in os.walk(OBSIDIAN_VAULT_PATH):
for file in files:
if file.endswith(".md"):
El bucle for garantiza que cada archivo Markdown del vault se procese automáticamente, copiando imágenes y actualizando links.
Una vez que Python termina su trabajo, el script de PowerShell retoma el control para subir los cambios a la web:
- Navega al repositorio local del blog (Astro).
- Hace un
git add .ygit commitcon los nuevos cambios. - Hace
git pusha la rama master, lo que dispara el despliegue automático en S3.
Gracias a esto, desde que escribo la última palabra en Obsidian hasta que está publicado, solo tengo que escribir un comando en la terminal. Es como tener un asistente invisible… que no habla y nunca pide vacaciones.
3. El blog está hecho con Astro
El blog en sí está programado por mí usando Astro y lo tengo embebido en mi página web. Partí de un repositorio llamado Blogster y le hice algunas modificaciones:
- Añadí campos para que los tags aparezcan en varios lugares.
- Hice que las imágenes se vean tanto en el post como en la lista de posts.
- Y en general lo hice un poco más visual y bonito.
Es decir, tomé algo que funcionaba y lo tuneé a mi gusto, porque no podía quedarme con la versión “de serie”.
4. Deploy automático con GitHub Actions y S3
Para que todo esto llegue a la web sin que yo tenga que tocar nada, uso GitHub Actions. La acción básicamente hace esto:
- Configura el job.
- Hace checkout del repositorio.
- Configura Node.js e instala dependencias.
- Construye el proyecto Astro.
- Despliega todo al bucket de Amazon S3.
- Termina el job.
Así, cada vez que hago push desde VS Code, todo se despliega solo. Sí, a veces tarda un poco en actualizarse (Cloudflare y sus DNS conspirando, imagino), pero en un día funciona perfecto y yo puedo olvidarme del tema.
5. Publicación automática en LinkedIn (Adiós Medium, hola MCP y Claude)
Finalmente, solía publicar en Medium, pero su API y yo tuvimos "diferencias irreconciliables" (básicamente me obligaban a hacer pasos manuales). Así que decidí modernizarme y pasarme al siguiente nivel de automatización.
Ahora, utilizo Claude Code conectado a mi servidor de n8n mediante un servidor MCP (Model Context Protocol). El flujo es pura belleza técnica:
- Claude Code lee mi post finalizado.
- A través del protocolo MCP, se conecta directamente con mi instancia de n8n en mi homelab.
- Le envía el contenido y las instrucciones precisas.
- n8n ejecuta el workflow y publica el artículo directamente en LinkedIn, formateado y listo para que lo leáis.
Sin copiar y pegar, sin pasos intermedios manuales y sin dramas de API. Ahora sí, puedo decir que desde que escribo en Obsidian hasta que el post aparece en mi web y en mis redes, el proceso es 100% automático. ¡El sueño de cualquier vago productivo!